package com.my.resquest;

import com.alibaba.fastjson2.JSON;
import com.my.model.RequestMap;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author WangLuoXin
 * &#064;Date 2024/9/12  14:54
 **/
public class NettyHttpRequest {

    private final HttpDataFactory dataFactory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE);

    /**
     * POST请求 json数据
     */
    private String bodyData;

    /**
     * form data数据
     */
    private RequestMap formData;

    /**
     * 原生 http请求
     */
    private FullHttpRequest request;

    /**
     * 路径参数
     */
    private RequestMap pathVariable;

    /**
     * 文件字节流 key 接收属性名
     */
    private final Map<String, FileUpload> files = new HashMap<>();

    /**
     * 加载 post json 数据
     */
    public void parseJson() {
        //application/json
        if (!request.method().name().equals("POST") || !request.headers().get(HttpHeaderNames.CONTENT_TYPE).startsWith(HttpHeaderValues.APPLICATION_JSON.toString())) {
            return;
        }
        ByteBuf content = request.content();
        bodyData = content.toString(StandardCharsets.UTF_8);
    }

    /**
     * 加载 x-www-form-urlencoded 表单数据
     */
    private void parseFormUrlencoded() {
        //www-form-urlencoded
        if (null != request.headers().get(HttpHeaderNames.CONTENT_TYPE) && !request.headers().get(HttpHeaderNames.CONTENT_TYPE).startsWith("application/x-www-form-urlencoded")) {
            return;
        }
        ByteBuf content = request.content();
        String contentString = content.toString(StandardCharsets.UTF_8);
        // 解析请求体中的表单参数
        QueryStringDecoder decoder = new QueryStringDecoder(contentString, false);
        Map<String, List<String>> parameters = decoder.parameters();

        RequestMap data = new RequestMap();
        for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
            String key = entry.getKey();
            List<String> values = entry.getValue();
            if (values.size() > 1) {
                data.put(key, values);
            } else {
                data.put(key, values.get(0));
            }
        }
        String uri = request.uri();
        if (uri.contains("?")) {
            String[] split = uri.split("\\?");
            split = split[1].split("&");
            for (String s : split) {
                split = s.split("=");
                try {
                    data.put(split[0], URLDecoder.decode(split[1], StandardCharsets.UTF_8.name()));
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        formData = data;
    }

    /**
     * 获取 form-data格式数据 如文件等
     */
    private void parseFormData() {
        // 确保请求方法是POST，并且内容类型是multipart/form-data
        if (null != request.headers().get(HttpHeaderNames.CONTENT_TYPE) && request.headers().get(HttpHeaderNames.CONTENT_TYPE).startsWith("multipart/form-data")) {
            // 创建 HttpPostRequestDecoder 来解析请求体
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(dataFactory, request);
            try {
                RequestMap dataMap = new RequestMap();
                // 读取数据
                while (decoder.hasNext()) {
                    InterfaceHttpData data = decoder.next();
                    if (data != null) {
                        if (data instanceof Attribute) {
                            Attribute attribute = (Attribute) data;
                            dataMap.put(attribute.getName(), attribute.getValue());
                        } else if (data instanceof FileUpload) {
                            // TODO 处理文件上传 暂未完善
                            FileUpload fileUpload = (FileUpload) data;
                            System.out.println("File: " + fileUpload.getName() + ", File Name: " + fileUpload.getFilename());
                            files.put(fileUpload.getName(), fileUpload);
                        }
                    }
                }
                formData = dataMap;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public String getBodyData() {
        if (null == bodyData) {
            parseJson();
        }
        return bodyData;
    }

    public <T> T getBodyData(Class<T> tClass) {
        if (null == bodyData) {
            parseJson();
        }
        return JSON.parseObject(bodyData, tClass);
    }

    public RequestMap getFormData() {
        if (null == formData) {
            parseFormData();
        }
        if (null == formData) {
            parseFormUrlencoded();
        }
        return formData;
    }

    public <T> T getFormData(Class<T> tClass) {
        if (null == formData) {
            parseFormData();
        }
        if (null == formData) {
            parseFormUrlencoded();
        }
        return JSON.parseObject(JSON.toJSONString(formData), tClass);
    }

    public FullHttpRequest getRequest() {
        return request;
    }

    public void setRequest(FullHttpRequest request) {
        this.request = request;
    }

    public RequestMap getPathVariable() {
        return pathVariable;
    }

    public void setPathVariable(RequestMap pathVariable) {
        this.pathVariable = pathVariable;
    }

    public FileUpload getFile(String fileName) {
        return files.get(fileName);
    }
}
